## IRQ HANDLING ROUTINES ##

.global irq0
.global irq1
.global irq2
.global irq3
.global irq4
.global irq5
.global irq6
.global irq7
.global irq8
.global irq9
.global irq10
.global irq11
.global irq12
.global irq13
.global irq14
.global irq15

# 32: IRQ0
irq0:
    cli
	pushb $0
    pushb $32
    jmp irq_common_stub

# 33: IRQ1
irq1:
    cli
    pushb $0
    pushb $33
    jmp irq_common_stub

# 34: IRQ2
irq2:
    cli
    pushb $0
    pushb $34
    jmp irq_common_stub

# 35: IRQ3
irq3:
    cli
    pushb $0
    pushb $35
    jmp irq_common_stub

# 36: IRQ4
irq4:
    cli
    pushb $0
    pushb $36
    jmp irq_common_stub

# 37: IRQ5
irq5:
    cli
    pushb $0
    pushb $37
    jmp irq_common_stub

# 38: IRQ6
irq6:
    cli
    pushb $0
    pushb $38
    jmp irq_common_stub

# 39: IRQ7
irq7:
    cli
    pushb $0
    pushb $39
    jmp irq_common_stub

# 40: IRQ8
irq8:
    cli
    pushb $0
    pushb $40
    jmp irq_common_stub

# 41: IRQ9
irq9:
    cli
    pushb $0
    pushb $41
    jmp irq_common_stub

# 42: IRQ10
irq10:
    cli
    pushb $0
    pushb $42
    jmp irq_common_stub

# 43: IRQ11
irq11:
    cli
    pushb $0
    pushb $43
    jmp irq_common_stub

# 44: IRQ12
irq12:
    cli
    pushb $0
    pushb $44
    jmp irq_common_stub

# 45: IRQ13
irq13:
    cli
    pushb $0
    pushb $45
    jmp irq_common_stub

# 46: IRQ14
irq14:
    cli
    pushb $0
    pushb $46
    jmp irq_common_stub

# 47: IRQ15
irq15:
    cli
    pushb $0
    pushb $47
    jmp irq_common_stub

# handles irq calls - two bytes already pushed - error code and interrupt number
irq_common_stub:

	# push all general registers (eax et al)
	pusha

	# push segments
	push %ds
	push %es
	push %fs
	push %gs

	# use kernel segments
	movw $0x10,%ax
	movw %ax,%ds
	movw %ax,%es
	movw %ax,%fs
	movw %ax,%gs
	
	# save the current task's esp, also you could store the kstack, cr3 etc...
	movl %esp,(current_task)

	# put esp into eax
	movl %esp,%eax
	
	# push the old value of esp
	push %eax

	# call the IRQ handler
	call irq_handler

	# restore EAX/ESP
	pop %eax
	
	# restore the new stack pointer
	movl (current_task),%esp
	
	# move the pointer into ebx
	movl $current_task,%ebx
	
	# move the kernel stack into the TSS
	movl 4(%ebx),%eax
	movl $global_tss,%ecx
	movl %eax,4(%ecx)
	movl $0x10,8(%ecx)

	# restore segments
	pop %gs
	pop %fs
	pop %es
	pop %ds

	# restore general registers
	popa

	# skip over intnum and errcode
	add $8,%esp

	# return
	iret
